package com.renhui.videoplayer;

import java.util.Timer;
import java.util.TimerTask;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.VideoView;

/***
 * 全屏视频播放
 * 
 * @author renhui
 */
public class VideoFullScreenActivity extends Activity implements View.OnClickListener, SeekBar.OnSeekBarChangeListener, MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener, View.OnTouchListener {

	private static final String TAG = "VideoFullScreenActivity";

	private boolean SHOULD_RELOAD_VIDEO = false;
	private boolean SHOULD_CONTINUE_AFTER_RELOAD = false;
	
	private int mThreshold = 80;
	private float mDownX;
	private float mDownY;
	private boolean mChangeVolume = false;
	private boolean mChangePosition = false;
	private int mGestureDownVolume;
	private int mDownPosition;
	private int mSeekTimePosition;//change postion when finger up
	
	private int mScreenWidth;
	private int mScreenHeight;
	private AudioManager mAudioManager;

	private String videoUrl; // 视频连接
	private int currentPosition = 0;
	

	// 更新进度条时间任务
	protected static Timer UPDATE_PROGRESS_TIMER;
	protected ProgressTimerTask mProgressTimerTask;

	// 隐藏控制View时间任务
	protected static Timer DISSMISS_CONTROL_VIEW_TIMER;
	protected DismissControlViewTimerTask mDismissControlViewTimerTask;
	
	// 隐藏控制音量对话框的时间任务
	protected static Timer DISSMISS_VOLUMDIALOG_TIMER;
	protected DismissVolumDialogTimerTask mDismissVolumDialogTimerTask;

	private RelativeLayout textureViewContainer; // 视频播放界面的容器(在本控件内不填充View，只用来处理事件)
	private ViewGroup topContainer;
	private ViewGroup bottomContainer;

	private VideoView videoView;
	private ImageView backButton;
	private ImageView startButton;

	private TextView currentTimeTextView, totalTimeTextView; // 当前时间 和 总时间
	private SeekBar progressBar; // 进度条
	private ProgressBar loadingProgressBar;
	
	protected Dialog mVolumeDialog;
	protected ProgressBar mDialogVolumeProgressBar;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		SHOULD_RELOAD_VIDEO = false; // 初始化参数
		videoUrl = getIntent().getStringExtra("video_url");
		setupFullScreen(); // 设置全屏参数
		setContentView(R.layout.activity_video_full_screen);
		initViews(); // 初始化UI
		setUpVideo();
	}

	private void initViews() {
		videoView = (VideoView) findViewById(R.id.fullVideo);
		textureViewContainer = (RelativeLayout) findViewById(R.id.surface_container);
		backButton = (ImageView) findViewById(R.id.back);
		startButton = (ImageView) findViewById(R.id.start);
		progressBar = (SeekBar) findViewById(R.id.progress);
		currentTimeTextView = (TextView) findViewById(R.id.current);
		totalTimeTextView = (TextView) findViewById(R.id.total);
		topContainer = (ViewGroup) findViewById(R.id.layout_top);
		bottomContainer = (ViewGroup) findViewById(R.id.layout_bottom);
		loadingProgressBar = (ProgressBar) findViewById(R.id.loading);

		backButton.setOnClickListener(this);
		startButton.setOnClickListener(this);
		bottomContainer.setOnClickListener(this);
		textureViewContainer.setOnClickListener(this);
		progressBar.setOnSeekBarChangeListener(this);
		textureViewContainer.setOnTouchListener(this);

		videoView.setOnErrorListener(this);
		videoView.setOnPreparedListener(this);
		videoView.setOnCompletionListener(this);
		
		mScreenWidth = getResources().getDisplayMetrics().widthPixels;
        mScreenHeight = getResources().getDisplayMetrics().heightPixels;
        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
	}
	
	/** 设置 Video 播放的URL参数  并请求视频播放的焦点 **/
	private void setUpVideo() {
		Uri uri = Uri.parse(videoUrl);
		videoView.setVideoURI(uri);
		videoView.requestFocus();
		videoView.start();
		startProgressTimer();
		startDismissControlViewTimer();
	}

	/** 设置全屏参数 */
	private void setupFullScreen() {
		// 设置全屏参数
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
		View decor = this.getWindow().getDecorView();
		decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
	}

	@Override
	protected void onResume() {
		super.onResume();
		// 判断是否需要重新加载Video，如果不需要，此判断后面的逻辑不进行
		if (!SHOULD_RELOAD_VIDEO) {
			return;
		}

		videoView.resume();
		videoView.start();
		videoView.seekTo(currentPosition);
		startProgressTimer();
		loadingProgressBar.setVisibility(View.VISIBLE);
		SHOULD_RELOAD_VIDEO = false;
	}

	@Override
	protected void onPause() {
		super.onPause();
		Log.e(TAG, "onPause");
		currentPosition = videoView.getCurrentPosition();
		if (videoView.isPlaying()) {
			SHOULD_CONTINUE_AFTER_RELOAD = true;
		} else {
			SHOULD_CONTINUE_AFTER_RELOAD = false;
		}
		videoView.pause();
		cancelProgressTimer();  // 为了防止锁屏的时候出现崩溃
	}

	@Override
	protected void onStop() {
		super.onStop();
		Log.e(TAG, "onStop");
		SHOULD_RELOAD_VIDEO = true;
		videoView.stopPlayback();
		dismissProgressDialog();
		dismissVolumDialog();
	}

	// 更新 开始播放 按钮的 图片
	private void updateStartImage() {
		if (videoView.isPlaying()) {
			startButton.setImageResource(R.drawable.jc_click_pause_selector);
		} else {
			startButton.setImageResource(R.drawable.jc_click_play_selector);
		}
	}

	// 展示 播放错误 的图片
	private void showErrorImage() {
		startButton.setImageResource(R.drawable.jc_click_error_selector);
		showControlViews();
	}

	// 展示 控制
	private void showControlViews() {
		topContainer.setVisibility(View.VISIBLE);
		bottomContainer.setVisibility(View.VISIBLE);
		startButton.setVisibility(View.VISIBLE);
	}

	// 隐藏控制
	private void hideControlViews() {
		topContainer.setVisibility(View.INVISIBLE);
		bottomContainer.setVisibility(View.INVISIBLE);
		startButton.setVisibility(View.INVISIBLE);
	}

	// 获取播放时长
	protected int getDuration() {
		int duration = 0;
		duration = videoView.getDuration();
		return duration;
	}

	/** 开始进度条时间任务 */
	protected void startProgressTimer() {
		cancelProgressTimer();
		UPDATE_PROGRESS_TIMER = new Timer();
		mProgressTimerTask = new ProgressTimerTask();
		UPDATE_PROGRESS_TIMER.schedule(mProgressTimerTask, 0, 300);
	}

	/** 取消进度条时间任务 */
	protected void cancelProgressTimer() {
		if (UPDATE_PROGRESS_TIMER != null) {
			UPDATE_PROGRESS_TIMER.cancel();
		}
		if (mProgressTimerTask != null) {
			mProgressTimerTask.cancel();
		}
	}

	// 开始隐藏控制View的时间任务
	private void startDismissControlViewTimer() {
		cancelDismissControlViewTimer();
		DISSMISS_CONTROL_VIEW_TIMER = new Timer();
		mDismissControlViewTimerTask = new DismissControlViewTimerTask();
		DISSMISS_CONTROL_VIEW_TIMER.schedule(mDismissControlViewTimerTask, 3200);
	}

	private void cancelDismissControlViewTimer() {
		if (DISSMISS_CONTROL_VIEW_TIMER != null) {
			DISSMISS_CONTROL_VIEW_TIMER.cancel();
		}
		if (mDismissControlViewTimerTask != null) {
			mDismissControlViewTimerTask.cancel();
		}
	}
	
	private void startDismissVolumDialogTimer() {
		cancelDismissVolumDialogTimer();
		DISSMISS_VOLUMDIALOG_TIMER = new Timer();
		mDismissVolumDialogTimerTask = new DismissVolumDialogTimerTask();
		DISSMISS_VOLUMDIALOG_TIMER.schedule(mDismissVolumDialogTimerTask, 2500);
	}

	private void cancelDismissVolumDialogTimer() {
		if (DISSMISS_VOLUMDIALOG_TIMER != null) {
			DISSMISS_VOLUMDIALOG_TIMER.cancel();
		}
		if (mDismissVolumDialogTimerTask != null) {
			mDismissVolumDialogTimerTask.cancel();
		}
	}

	// 获取当前的播放位置
	protected int getCurrentPositionWhenPlaying() {
		int position = 0;
		position = videoView.getCurrentPosition();
		return position;
	}

	protected void setTextAndProgress(int secProgress) {
		int position = getCurrentPositionWhenPlaying();
		int duration = getDuration();
		int progress = position * 100 / (duration == 0 ? 1 : duration);
		setProgressAndTime(progress, secProgress, position, duration);
	}

	protected void setProgressAndTime(int progress, int secProgress, int currentTime, int totalTime) {
		if (progress != 0)
			progressBar.setProgress(progress);
		if (secProgress != 0)
			progressBar.setSecondaryProgress(secProgress);
		currentTimeTextView.setText(VideoUtils.stringForTime(currentTime));
		totalTimeTextView.setText(VideoUtils.stringForTime(totalTime));
	}

	// “进度条” 时间任务
	protected class ProgressTimerTask extends TimerTask {
		@Override
		public void run() {
			if (getDuration() == -1) {
				return;
			}

			runOnUiThread(new Runnable() {
				@Override
				public void run() {
					// 更新播放状态和播放进度
					setTextAndProgress(videoView.getBufferPercentage());
					updateStartImage();
				}
			});
		}
	}

	// 隐藏控制控件时间任务
	protected class DismissControlViewTimerTask extends TimerTask {

		@Override
		public void run() {
			if (getDuration() == -1) {
				return;
			}

			runOnUiThread(new Runnable() {
				@Override
				public void run() {
					topContainer.setVisibility(View.INVISIBLE);
					bottomContainer.setVisibility(View.INVISIBLE);
					startButton.setVisibility(View.INVISIBLE);
					dismissVolumDialog();
				}
			});
		}
	}
	
	
	// 隐藏声音对话框时间任务
	protected class DismissVolumDialogTimerTask extends TimerTask {

		@Override
		public void run() {
			runOnUiThread(new Runnable() {
				@Override
				public void run() {
					dismissVolumDialog();
				}
			});
		}
	}
	
	/**展示声音调整对话框*/
	@SuppressLint("InflateParams")
	private void showVolumDialog(float deltaY, int volumePercent) {
		if (mVolumeDialog == null) {
			View localView = LayoutInflater.from(this).inflate(R.layout.jc_volume_dialog, null);
			mDialogVolumeProgressBar = ((ProgressBar) localView.findViewById(R.id.volume_progressbar));
			mVolumeDialog = new Dialog(this, R.style.jc_style_dialog_progress);
			mVolumeDialog.setContentView(localView);
			mVolumeDialog.getWindow().addFlags(8);
			mVolumeDialog.getWindow().addFlags(32);
			mVolumeDialog.getWindow().addFlags(16);
			mVolumeDialog.getWindow().setLayout(-2, -2);
			WindowManager.LayoutParams localLayoutParams = mVolumeDialog.getWindow().getAttributes();
			localLayoutParams.gravity = 19;
			localLayoutParams.x = getResources().getDimensionPixelOffset(R.dimen.jc_volume_dialog_margin_left);
			mVolumeDialog.getWindow().setAttributes(localLayoutParams);
		}
		if (!mVolumeDialog.isShowing()) {
			mVolumeDialog.show();
		}

		mDialogVolumeProgressBar.setProgress(volumePercent);
	}
	
	/**隐藏声音调整对话框*/
	private void dismissVolumDialog() {
		if (mVolumeDialog != null) {
			mVolumeDialog.dismiss();
		}
	}


	// 主要是设置 seek 完成的监听操作
	@Override
	public void onPrepared(MediaPlayer mp) {
		mp.setOnSeekCompleteListener(new OnSeekCompleteListener() {

			@Override
			public void onSeekComplete(MediaPlayer mp) {
				loadingProgressBar.setVisibility(View.INVISIBLE);
				if (!SHOULD_CONTINUE_AFTER_RELOAD) {
					videoView.pause();
					updateStartImage();
				}
			}
		});
	}

	// 播放完成后的操作
	@Override
	public void onCompletion(MediaPlayer mp) {
		cancelProgressTimer();
		videoView.stopPlayback();
		Uri uri = Uri.parse(videoUrl);
		videoView.setVideoURI(uri);
		videoView.requestFocus();
	}

	// 当播放出错后的回调
	@Override
	public boolean onError(MediaPlayer mp, int what, int extra) {
		showErrorImage();
		videoView.stopPlayback();
		Uri uri = Uri.parse(videoUrl);
		videoView.setVideoURI(uri);
		videoView.requestFocus();
		return true;
	}

	@Override
	public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
		if (getDuration() != -1 && fromUser) {

			if (videoView.isPlaying()) {
				SHOULD_CONTINUE_AFTER_RELOAD = true;
			} else {
				SHOULD_CONTINUE_AFTER_RELOAD = false;
			}

			int time = progress * getDuration() / 100;
			videoView.seekTo(time);
			startButton.setVisibility(View.INVISIBLE);
			loadingProgressBar.setVisibility(View.VISIBLE); // 展示loading效果
			Log.d(TAG, "seekTo " + time + " [" + this.hashCode() + "] ");
		}

	}

	@Override
	public void onStartTrackingTouch(SeekBar seekBar) {
	}

	@Override
	public void onStopTrackingTouch(SeekBar seekBar) {
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {

		case R.id.back:
			finish();
			break;

		case R.id.start:
			if (videoView.isPlaying()) {
				videoView.pause();
				updateStartImage();
			} else {
				videoView.start();
				updateStartImage();
				startProgressTimer();
				startDismissControlViewTimer();
			}
			break;

		case R.id.surface_container:
			onClickUiToggle();
			break;

		default:
			break;
		}
	}
	
	@SuppressLint("ClickableViewAccessibility")
	@Override
	public boolean onTouch(View v, MotionEvent event) {
		 float x = event.getX();
	     float y = event.getY();
	     if (v.getId() == R.id.surface_container) {
	    	 switch (event.getAction()) {
	            case MotionEvent.ACTION_DOWN:
	                mDownX = x;
	                mDownY = y;
	                mChangeVolume = false;
	                mChangePosition = false;
	                break;
	                
	            case MotionEvent.ACTION_MOVE:
	                float deltaX = x - mDownX;
	                float deltaY = y - mDownY;
	                float absDeltaX = Math.abs(deltaX);
	                float absDeltaY = Math.abs(deltaY);
	                if (!mChangePosition && !mChangeVolume) {
	                    if (absDeltaX > mThreshold || absDeltaY > mThreshold) {
	                        if (absDeltaX >= mThreshold) {
	                        	cancelProgressTimer();
	                        	mChangePosition = true;
                                mDownPosition = getCurrentPositionWhenPlaying();
	                        } else {
	                            mChangeVolume = true;
	                            mGestureDownVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
	                        }
	                    }
	                }
	                
	                if (mChangePosition) {
                        int totalTimeDuration = getDuration();
                        mSeekTimePosition = (int) (mDownPosition + deltaX * totalTimeDuration / mScreenWidth);
                        if (mSeekTimePosition > totalTimeDuration)
                            mSeekTimePosition = totalTimeDuration;
                        String seekTime = VideoUtils.stringForTime(mSeekTimePosition);
                        String totalTime = VideoUtils.stringForTime(totalTimeDuration);
                        showProgressDialog(deltaX, seekTime, mSeekTimePosition, totalTime, totalTimeDuration);
                    }
	                
	                if (mChangeVolume) {
	                    deltaY = -deltaY;
	                    int max = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
	                    int deltaV = (int) (max * deltaY * 2 / mScreenHeight);
	                    mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mGestureDownVolume + deltaV, 0);
	                    int volumePercent = (int) (mGestureDownVolume * 100 / max + deltaY * 2 * 100 / mScreenHeight);
	                    showVolumDialog(-deltaY, volumePercent);
	                }

	                break;
	            case MotionEvent.ACTION_UP:
	            	startDismissVolumDialogTimer();
	            	dismissProgressDialog();
                    if (mChangePosition) {
                    	if (videoView.isPlaying()) {
            				SHOULD_CONTINUE_AFTER_RELOAD = true;
            			} else {
            				SHOULD_CONTINUE_AFTER_RELOAD = false;
            			}
                    	
                    	videoView.seekTo(mSeekTimePosition);
                    	showControlViews();
                    	startDismissControlViewTimer();
                    }
                    /////////////////////
                    startProgressTimer();
                    break;
	        }
	     }
		return false;
	}
	
	private Dialog mProgressDialog;
	private ProgressBar mDialogProgressBar;
	private TextView mDialogSeekTime;
	private TextView mDialogTotalTime;
	private ImageView mDialogIcon;

	@SuppressLint("InflateParams")
	private void showProgressDialog(float deltaX, String seekTime, int seekTimePosition, String totalTime, int totalTimeDuration) {
		if (mProgressDialog == null) {
			View localView = LayoutInflater.from(this).inflate(R.layout.jc_progress_dialog, null);
			mDialogProgressBar = ((ProgressBar) localView.findViewById(R.id.duration_progressbar));
			mDialogSeekTime = ((TextView) localView.findViewById(R.id.tv_current));
			mDialogTotalTime = ((TextView) localView.findViewById(R.id.tv_duration));
			mDialogIcon = ((ImageView) localView.findViewById(R.id.duration_image_tip));
			mProgressDialog = new Dialog(this, R.style.jc_style_dialog_progress);
			mProgressDialog.setContentView(localView);
			mProgressDialog.getWindow().addFlags(Window.FEATURE_ACTION_BAR);
			mProgressDialog.getWindow().addFlags(32);
			mProgressDialog.getWindow().addFlags(16);
			mProgressDialog.getWindow().setLayout(-2, -2);
			WindowManager.LayoutParams localLayoutParams = mProgressDialog.getWindow().getAttributes();
			localLayoutParams.gravity = 49;
			localLayoutParams.y = getResources().getDimensionPixelOffset(R.dimen.jc_progress_dialog_margin_top);
			mProgressDialog.getWindow().setAttributes(localLayoutParams);
		}
		if (!mProgressDialog.isShowing()) {
			mProgressDialog.show();
		}

		mDialogSeekTime.setText(seekTime);
		mDialogTotalTime.setText(" / " + totalTime);
		mDialogProgressBar.setProgress(seekTimePosition * 100 / totalTimeDuration);
		if (deltaX > 0) {
			mDialogIcon.setBackgroundResource(R.drawable.jc_forward_icon);
		} else {
			mDialogIcon.setBackgroundResource(R.drawable.jc_backward_icon);
		}
	}
	
	private void dismissProgressDialog() {
		if (mProgressDialog != null) {
			mProgressDialog.dismiss();
		}
	}

	// UI 切换 主要负责 控制的显示与否
	private void onClickUiToggle() {
		if (bottomContainer.getVisibility() == View.VISIBLE) {
			hideControlViews();
		} else {
			showControlViews();
			startDismissControlViewTimer();
		}
	}
}
